package com.douyang.util;


import org.redisson.api.RScript;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;

@Component
public class LuaScriptUtil {
    @Autowired
    private RedissonClient redissonClient;

    public static String getLuaScriptInsertIfExists() {
        return """
                local key = KEYS[1]       -- 第一个参数是 key
                local value = ARGV[1]     -- 第二个参数是 value

                -- 检查 key 是否存在
                local exists = redis.call("EXISTS", key)

                if exists == 0 then
                    -- 如果 key 不存在，插入 key 和 value
                    redis.call("SET", key, value)
                    return tonumber(value)  -- 返回插入的值
                else
                    -- 如果 key 存在，返回当前值
                    return tonumber(redis.call("GET", key))
                end
                
                """;
    }


    public static String getLuaScriptWithStock() {
        return """
                local key = KEYS[1]        -- 第一个参数是 key
                local number = tonumber(ARGV[1])  -- 第二个参数是要增加的数量（number）
                
                if redis.call("EXISTS", key) == 0 then
                    return 0
                end
                
                -- 获取当前库存
                local stock = tonumber(redis.call('GET', key))  -- 如果 key 不存在，则默认为 0
   
                if number > 0 then
                    -- 如果 number 是正数，直接增加库存
                    redis.call('INCRBY', key, number)
                    return 1  -- 返回 1 表示操作成功
                else
                    -- 如果 number 是负数，检查库存是否足够
                    if stock >= -number then
                        redis.call('INCRBY', key, number)
                        return 1  -- 返回 1 表示操作成功
                    else
                        return 0  -- 返回 0 表示库存不足，操作失败
                    end
               end
            """;
    }

    public Long tryToDeduction(String key,String number) {
        RScript script = redissonClient.getScript(StringCodec.INSTANCE);
        return script.eval(
                RScript.Mode.READ_WRITE, //读写模式
                getLuaScriptWithStock(),                // Lua 脚本
                RScript.ReturnType.INTEGER, // 返回值类型
                Collections.singletonList(key),       // KEYS 参数
                number                   // ARGV 参数
        );
    }

    public Long tryToInsert(String key,String data) {
        RScript script = redissonClient.getScript(StringCodec.INSTANCE);
        return script.eval(
                RScript.Mode.READ_WRITE,
                getLuaScriptInsertIfExists(),
                RScript.ReturnType.INTEGER,
                Collections.singletonList(key),
                data
        );
    }
}
